Custom Keyboard PRO
The CustomKeyboard namespace provides a comprehensive API for building fully custom keyboard UIs in the Scripting app. It allows you to create JSX-based keyboards, insert or modify text, query input state, respond to user interaction, and control keyboard layout or navigation.
1. Environment & Setup
Requirements
-
You must define your keyboard interface in a file named
**keyboard.tsx**inside your script project. -
The
CustomKeyboardAPI is only available in the keyboard extension environment. -
It is not available in App scripts, Intents (
intent.tsx), or Widgets (widget.tsx). -
You must enable the keyboard in iOS settings:
Then tap the Scripting Keyboard and enable Allow Full Access to unlock clipboard and network features.
2. Presentation
present(node: VirtualNode): void
Renders your custom keyboard UI using the given JSX node. This function must be called once in keyboard.tsx.
3. Text Input State
4. Input Traits
useTraits(): TextInputTraits
Hook to retrieve the current input traits (e.g., keyboard type, return key style). It automatically updates when textDidChange or selectionDidChange events occur.
traits: TextInputTraits
A snapshot of the traits at the last change. Prefer useTraits() in JSX components for reactivity.
Example fields:
keyboardType:'default','numberPad','emailAddress'...returnKeyType:'go','search','done'...autocapitalizationType:'none','sentences', etc.textContentType: semantic input hints like'username','oneTimeCode', etc.keyboardAppearance:'light','dark', etc.
5. Text Manipulation
insertText(text: string): Promise<void>
Insert text at the current cursor position.
deleteBackward(): Promise<void>
Delete one character before the cursor.
moveCursor(offset: number): Promise<void>
Move the cursor by a number of characters. Negative = left; Positive = right.
setMarkedText(text, location, length): Promise<void>
Mark a portion of inserted text (used in composition scenarios like Pinyin input).
unmarkText(): Promise<void>
Clear any currently marked text.
6. Keyboard Behavior Control
dismiss(): Promise<void>
Dismiss the keyboard view.
nextKeyboard(): Promise<void>
Switch to the next system keyboard.
requestHeight(height: number): Promise<void>
Request a new keyboard height in points. Recommended range is 216–360pt.
setHasDictationKey(value: boolean): Promise<void>
Control whether the dictation (microphone) key is shown.
setToolbarVisible(visible: boolean): Promise<void>
Show or hide the custom keyboard toolbar. Useful for debugging.
7. Navigation
dismissToHome(): Promise<void>
Dismisses the currently active keyboard script and returns to the Scripting keyboard home screen (script list). Useful for letting users choose another script.
8. User Feedback
playInputClick(): void
Play the standard system keyboard click sound. Useful when simulating real key taps.
9. Event Listeners
addListener(event, callback): void
Register a listener for keyboard or text input changes.
removeListener(event, callback): void
Remove a specific listener.
removeAllListeners(event): void
Remove all listeners for a given event type.
10. Full Example
11. Best Practices
- Call
present()only once in yourkeyboard.tsxfile. - Use
requestHeight()to ensure appropriate layout on different screen sizes. - Prefer
useTraits()for reactive input context access in JSX. - Use
dismissToHome()instead ofdismiss()if you want to return to the script list. - Call
playInputClick()when simulating key taps for user feedback. - Always check for
hasTextbefore callingdeleteBackward().
